<?php

namespace App\Service\OpenShop\Merchant;

use App\Console\Commands\SiteLocation\SummerSiteRobotPush;
use App\Enums\BaseErrorCode;
use App\Enums\OpenShop\InvestmentPromotion\MainProcessEnum;
use App\Enums\OpenShop\InvestmentPromotion\OrganizationManageEnum;
use App\Enums\OpenShop\InvestmentPromotion\SiteLocationEnum;
use App\Enums\OpenShop\InvestmentPromotion\SiteMissionEnum;
use App\Enums\OpenShop\MissionTemplateEnum;
use App\Events\OpenShop\OpenShopProcessEvent;
use App\Events\OpenShop\SignSiteMissionEvent;
use App\Events\OpenShop\SignToPositionTimeEvent;
use App\Exceptions\Custom\ResponseHttpException;
use App\Http\Middleware\OpenShop\MerchantAppAuth;
use App\Http\Middleware\OpenShop\UserPermissionAuth;
use App\Http\Resources\OpenShop\ShopLocation\SiteMissionResource;
use App\Library\FeiShu\SendFs;
use App\Library\Rms\RmsPayApi;
use App\Models\Appraise\AppraiseModel;
use App\Models\Common\ConfigModel;
use App\Models\Cruise\CruiseOrderExamineLogModel;
use App\Models\OpenShop\Common\OpenShopOrderManagerModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopAddressModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopLocationModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopMainProcessModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopOrganizationRegionMappingModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSignOrderModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSiteMissionModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSpaceDesignCostMappingModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSpaceDesignModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopUserBaseInfoModel;
use App\Models\OpenShop\SiteLocation\OpenShopSiteLocationExamineLogModel;
use App\Models\OpenShop\SiteLocation\OpenShopSiteLocationModel;
use App\Models\Wanggui\CustomerDepartmentSiteLocationRelationModel;
use App\Remote\Rms\RmsShopRemote;
use App\Service\OpenShop\Feishu\BaseService;
use App\Service\OpenShop\Feishu\MessageSendService;
use App\Service\OpenShop\Feishu\OrganizationManageService;
use App\Service\OpenShop\Feishu\SelectionService;
use App\Service\OpenShop\Feishu\ShopTagsService;
use App\Service\OpenShop\FeishuMini\CustomerDepartmentService;
use App\Service\OpenShop\SiteLocation\PlaceHolderSiteLocationService;
use App\Service\OpenShop\User\RmsUserService;
use App\Service\Rms\ShopService;
use App\Service\WorkOrder\Appraise\NotifyService;
use App\Support\FeishuMsgSupport;
use Carbon\Carbon;
use Exception;
use Guanguans\Notify\Factory;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Kuafu\GeneralFs\BuildFs;

/**
 * Class SiteMissionService
 * @package App\Service\OpenShop\Merchant
 */
class SiteMissionService
{


    /**
     * 任务列表
     *
     * @throws Exception
     */
    public static function missionList(int $shopId): array
    {

        try {
            $orderObj = OpenShopMainProcessModel::query()
                                                ->where("shopId", $shopId)
//                                                ->orderBy('id', 'desc')
                                                ->first();

            if (!$orderObj) {
                throw new ResponseHttpException(BaseErrorCode::$ORDER_NOT_EXISTS);
            }

            $missionList = SiteMissionResource::collection(OpenShopSiteMissionModel::query()
                                                                                   ->where("orderNo",
                                                                                       $orderObj->orderNo)
                                                                                   ->where("handlerType",
                                                                                       MissionTemplateEnum::HANDLER_TYPE_MERCHANT)
                                                                                   ->get());

            $stay = $missionList->resource->where("status", SiteMissionEnum::STATUS_1)->values();
//            $count = 0;
//            foreach ($stay as $key => $item) {
//                if ($count > 0 && $item->stepStatus == MissionTemplateEnum::STEP_STATUS_16) {
//                    unset($stay[$key]);
//                    continue;
//                }
//                if ($item->stepStatus == MissionTemplateEnum::STEP_STATUS_16) {
//                    ++$count;
//                }
//            }
            return [
                "missionList" => [
                    "stay"   => $stay->values(),
                    "finish" => $missionList->resource->where("status", SiteMissionEnum::STATUS_2)->values()
                ]
            ];
        } catch (Exception $exception) {
            handleException($exception, BaseErrorCode::$MISSION_LIST_GET_FAIL);
        }

    }


    /**
     * 更新确认选址信息
     *
     * @param int $shopId
     * @param int $missionId
     * @throws Exception
     */
    public static function confirmShopLocation(int $shopId, int $missionId, int $merchantConfirmTime = 0)
    {
        if (!$merchantConfirmTime) {
            $merchantConfirmTime = time();
        }

        try {
            DB::beginTransaction();
            $orderObj = OpenShopMainProcessModel::query()
                                                ->where("shopId", $shopId)
                                                ->first();
            if (!$orderObj) {
                throw new ResponseHttpException(BaseErrorCode::$ORDER_NOT_EXISTS);
            }

            $missionRes = OpenShopSiteMissionModel::query()
                                                  ->where("orderNo", $orderObj->orderNo)
                                                  ->where("id", $missionId)
                                                  ->where("stepStatus", MissionTemplateEnum::STEP_STATUS_5)
                                                  ->where("status", SiteMissionEnum::STATUS_1)
                                                  ->update([
                                                      "status"    => SiteMissionEnum::STATUS_2,
                                                      "updatedAt" => time(),
                                                      "dealUid"   => MerchantAppAuth::$userId
                                                  ]);



            (new PlaceHolderSiteLocationService($orderObj->orderNo))->clearPlaceHolder();

            $shopLocationRes = OpenShopLocationModel::query()
                                                    ->where("orderNo", $orderObj->orderNo)
                                                    ->update([
                                                        "step"          => MainProcessEnum::SHOP_LOCATION_CONFIRM,
                                                        "confirmStatus" => OpenShopLocationModel::CONFIRM_STATUS_ON,
                                                        "confirmTime"   => $merchantConfirmTime,
                                                        "updatedAt"     => time()
                                                    ]);

            //todo 切换到下一阶段流程 [空间设计] & 主流程变更
//            OpenShopSpaceDesignModel::query()->insert([
//                "mainProcessId" => $orderObj->id,
//                "orderNo"       => $orderObj->orderNo,
//                "createdAt"     => time()
//            ]);

            $orderObj->step = MainProcessEnum::MAIN_PROCESS_SPACE_DESIGN;
            $orderObj->save();

            if (!$missionRes || !$shopLocationRes) {
                throw new ResponseHttpException(BaseErrorCode::$MISSION_CONFIRM_SHOP_LOCATION_FAIL);
            }

            // 同步地址信息
            OpenShopAddressModel::autoAdd($orderObj->orderNo);

            $siteLocationModel = OpenShopSiteLocationModel::query()->whereIn('source',
                [
                    OpenShopSiteLocationModel::SOURCE_OPEN_SHOP,
                    OpenShopSiteLocationModel::SOURCE_HOUSING
                ])->where('orderNo', $orderObj->orderNo)->first();
            OpenShopSiteLocationExamineLogModel::query()->insert([
                "orderNo"      => $orderObj->orderNo,
                "source"       => $siteLocationModel->source,
                "type"         => OpenShopSiteLocationExamineLogModel::TYPE_BUSINESS_CONFIRM_SITE_LOCATION,
                "position"     => OpenShopSiteLocationExamineLogModel::POSITION_BUSINESS_EXAMINE,
                "status"       => OpenShopSiteLocationExamineLogModel::STATUS_OK,
                "createdAt"    => time(),
                "createdByUid" => MerchantAppAuth::$userId
            ]);

            //发送确址信息
            try {
                $shopCode = (int)optional($siteLocationModel->signOrderRel)->shopCode;

                SiteLocationPushMsgService::getCardMsg($orderObj->orderNo, $siteLocationModel, $merchantConfirmTime, $shopCode);

            } catch (\Exception|GuzzleException $exception) {
                Log::info("选址确认机器人推送出错： " . $exception->getMessage());
            }

            DB::commit();
            //任务触发
            event(new SignSiteMissionEvent(
                    $orderObj->orderNo,
                    MissionTemplateEnum::STEP_STATUS_5,
                    MerchantAppAuth::$userId)
            );
            //流程日志追加
            event(new OpenShopProcessEvent(
                0,
                $orderObj->id,
                MainProcessEnum::MAIN_PROCESS_SHOP_LOCATION,
                MainProcessEnum::SHOP_LOCATION_CONFIRM
            ));

            // 同步门店名称-rms
            $shopName = (string)OpenShopSiteLocationModel::query()
                                                         ->where('source', OpenShopSiteLocationModel::SOURCE_OPEN_SHOP)
                                                         ->where('orderNo', $orderObj->orderNo)
                                                         ->where('shopName', '!=', '')
                                                         ->value('shopName');
            if ($shopName) {
                ShopService::updateShopName($orderObj->orderNo, $shopName);
            }

            /**
             * 选址完成后更新订单信息
             */
            //获取订单基础信息
            $sitelocationModel = OpenShopSiteLocationModel::query()
                                                          ->where('orderNo', $orderObj->orderNo)
                                                          ->with(['openShopMainProcessRel', 'signOrderRel', 'identityCardRel'])
                                                          ->where('source', OpenShopSiteLocationModel::SOURCE_OPEN_SHOP)
                                                          ->first();

            OpenShopSiteLocationModel::query()->where('orderNo', $orderObj->orderNo)
                ->where('source', OpenShopSiteLocationModel::SOURCE_OPEN_SHOP)
                ->update([
                    'merchantConfirmTime' => $merchantConfirmTime,
                    'siteStatus'          => OpenShopSiteLocationModel::SITE_STATUS_21,
                    'handler'             => $sitelocationModel->developConsultantId
                ]);

            // 修改筹备信息
            // 根据省份获得省份筹备负责人
            $managerModel = OpenShopOrganizationRegionMappingModel::query()
                ->where('provinceCode', $sitelocationModel->provinceCode)
                ->with(['organizationManageRel'])
                ->first();

            if ($managerModel != null && $managerModel->organizationManageRel != null) {
                OpenShopOrderManagerModel::query()
                    ->where('mainProcessId', $sitelocationModel->mainProcessId)
                    ->where('type', OpenShopOrderManagerModel::MANAGER_TYPE_4)
                    ->update([
                        'managerUid'  => $managerModel->organizationManageRel->preparationUid,
                        'managerName' => $managerModel->organizationManageRel->preparationName,
                    ]);
            }

            $statusRes = CustomerDepartmentService::updateTaskProjectPhaseBySite(OpenShopSiteLocationModel::SOURCE_OPEN_SHOP, $siteLocationModel->id, OpenShopSiteLocationModel::SITE_STATUS_21);

            try {
                //给开发发消息
                $userInfo        = RmsUserService::getRmsUserInfoByUserIds([$sitelocationModel->developConsultantId])['data'] ?? [];
                $templateJson    = sprintf(file_get_contents(resource_path('OpenShop/feishu/notifyTemplate/leaseContractSubmit.json')),
                    (int)optional($sitelocationModel->signOrderRel)->shopCode,
                    (string)optional($sitelocationModel->identityCardRel)->name,
                    $sitelocationModel->address,
                    $sitelocationModel->cityArea,
                    $sitelocationModel->developConsultantName,
                    Carbon::now()->toDateString(),
                    BaseService::getSiteLocationAppletUrl(0, $sitelocationModel->orderNo),
                    (int)optional($sitelocationModel->signOrderRel)->shopCode
                );
                foreach (array_column($userInfo, 'feishuUserId') as $feishuId) {
                    MessageSendService::sendMessage($feishuId, 'user_id', json_decode($templateJson, true), 'interactive', UserPermissionAuth::MODULE_OPEN_SHOP);
                }

            } catch (\Exception $exception) {
                Log::info("门店ID{$shopId}商家已确认选址，给开发发送消息失败");
            }
            //获取筹备uid
            $manager = OrganizationManageService::getOrganizationInfoByType(OrganizationManageEnum::TYPE_BRANCH_OFFICE,
                $sitelocationModel->provinceCode);

            if ($manager && $manager["preparationUid"] > 0) {
                // 处理原订单
                OpenShopOrderManagerModel::generateManagerOrUpdate(
                    OpenShopOrderManagerModel::MANAGER_TYPE_4,
                    $sitelocationModel->mainProcessId,
                    $manager["preparationUid"],
                    $manager["preparationName"]
                );
                //空间设计表写入
                OpenShopSpaceDesignModel::query()->updateOrCreate(
                    [
                        'mainProcessId' => $sitelocationModel->mainProcessId,
                        'orderNo'       => $orderObj->orderNo
                    ],
                    [
                        "preparationUid"  => $manager["preparationUid"] ?? 0,
                        "preparationName" => $manager["preparationName"] ?? ""
                    ]
                );
            }

            // 判断子单
            if ($sitelocationModel->openShopMainProcessRel->childLocationOrder == MainProcessEnum::CHILD_ORDER_1) {
                // 处理原订单
                OpenShopOrderManagerModel::generateManagerOrUpdate(
                    OpenShopOrderManagerModel::MANAGER_TYPE_4,
                    $sitelocationModel->openShopMainProcessRel->locationPid,
                    $manager["preparationUid"],
                    $manager["preparationName"]
                );

                //空间设计表更新
                OpenShopSpaceDesignModel::query()->where('mainProcessId',
                    $sitelocationModel->openShopMainProcessRel->locationPid)
                                        ->update(
                                            [
                                                "preparationUid"  => $manager["preparationUid"] ?? 0,
                                                "preparationName" => $manager["preparationName"] ?? ""
                                            ]
                                        );
            }

            //选址阶段-在「商家确认选址信息」完成之后，进行推送 评价消息
            NotifyService::notify($orderObj->orderNo, AppraiseModel::TYPE_OPENSHOP_SET_LOCATION, 0, $shopId);

            // 更新标签
            (new ShopTagsService($orderObj->orderNo))->removeTagsAfterMerchantAddress();

            (new ShopTagsService($orderObj->orderNo))
                ->updateOrderPrepareTag(); // 生成筹备正常标签

            // 同步网商分账配置
            (new RmsPayApi(null))->addMyBankShareConfig($orderObj->orderNo);

            // 同步选址报告中填写的门店属性
            $syncShopAttributeData = [
                'shopType'                  => $siteLocationModel['shopType'],              //店型
                'siteSelection'             => $siteLocationModel['siteSelection'],         //选址场景 多个逗号隔开
                'sellingCategory'           => $siteLocationModel['sellingCategory'],       //售卖品类 多个逗号隔开
                'siteSelectionGrade'        => $siteLocationModel['siteSelectionGrade'],    //选址场景分级
                'menuLevel'                 => $siteLocationModel['menuLevel'],             //产品定价
                'posLine'                   => $siteLocationModel['posLine'],               //点餐动线
                'engineeringExhibitionArea' => $siteLocationModel['doorHeadWidth'],         //工程条件-展面
                'engineeringArea'           => $siteLocationModel['area'],                  //工程条件-面积
                'engineeringDepth'          => $siteLocationModel['depth'],                 //工程条件-进深
                'engineeringElectricity'    => $siteLocationModel['electricityConsumption'],//工程条件-电量
                'posType'                   => $siteLocationModel['caseRegisterType'],      //收银设备
                'shopStatusText'            => '筹备中',                                       //门店阶段-筹备中
            ];
            Log::info('debug_updateShopAttribute', ['syncShopAttributeData' => $syncShopAttributeData, 'shopId' => $shopId]);
            RmsShopRemote::updateShopAttribute($shopId, $syncShopAttributeData);

            // 落位时长入库
            event(new SignToPositionTimeEvent($orderObj->orderNo));

        } catch (Exception $exception) {
            DB::rollBack();
            handleException($exception, BaseErrorCode::$MISSION_CONFIRM_SHOP_LOCATION_FAIL);
        }
    }

    /**
     * 商家 驳回房源
     *
     * @param int $shopId
     * @param int $missionId
     * @param string $rejectReason
     * @throws Exception|GuzzleException
     */
    public static function rejectShopLocation(int $shopId, int $missionId, string $rejectReason)
    {

        try {
            $orderObj = OpenShopMainProcessModel::query()
                                                ->where("shopId", $shopId)
                                                ->first();
            if (!$orderObj) {
                throw new ResponseHttpException(BaseErrorCode::$ORDER_NOT_EXISTS);
            }

            $missionRes = OpenShopSiteMissionModel::query()
                                                  ->where("orderNo", $orderObj->orderNo)
                                                  ->where("id", $missionId)
                                                  ->where("stepStatus", MissionTemplateEnum::STEP_STATUS_5)
                                                  ->where("status", SiteMissionEnum::STATUS_1)
                                                  ->first();

            if (!$missionRes) {
                throw new ResponseHttpException(BaseErrorCode::$MISSION_NOT_EXISTS);
            }

            $siteLocationModel = OpenShopSiteLocationModel::query()->whereIn('source',
                [
                    OpenShopSiteLocationModel::SOURCE_OPEN_SHOP,
                    OpenShopSiteLocationModel::SOURCE_HOUSING
                ])->where("orderNo", $orderObj->orderNo)->first();

            OpenShopSiteLocationExamineLogModel::query()->insert([
                "orderNo"      => $orderObj->orderNo,
                "source"       => $siteLocationModel->source,
                "type"         => OpenShopSiteLocationExamineLogModel::TYPE_BUSINESS_CONFIRM_SITE_LOCATION,
                "position"     => OpenShopSiteLocationExamineLogModel::POSITION_BUSINESS_EXAMINE,
                "content"      => $rejectReason,
                "status"       => OpenShopSiteLocationExamineLogModel::STATUS_REFUSE,
                "createdAt"    => time(),
                "createdByUid" => MerchantAppAuth::$userId
            ]);

            // 获取省区处理人
            $provinceInfoBy = OrganizationManageService::getProvinceInfoByProvinceCode($siteLocationModel->provinceCode);
            //发送飞书消息
            FeishuMsgSupport::getInstance(
                "【加盟商驳回选址】有新的选址驳回选址意见通知，请注意（{$orderObj->signOrderRel->shopCode}）",
                array_merge(
                    [$provinceInfoBy['operationUid']],//省总
                    ConfigModel::getManager(ConfigModel::SITE_MANAGER), //选址负责人 - 赤瞳
                    ConfigModel::getManager(ConfigModel::SITE_SUPER_ADMIN),//总部负责人 - 大黄蜂
                    [$siteLocationModel->developConsultantId]//省区开发
                )
            )->setContent(
                [
                    "name"  => "门店编号名称",
                    "value" => vsprintf(
                        "%s夸父炸串（%s）",
                        [$orderObj->signOrderRel->shopCode, $siteLocationModel->shopName])
                ],
                ["name" => "申请人", "value" => $siteLocationModel->identityCardRel->name],
                ["name" => "申请角色", "value" => "加盟商"],
                ["name" => '详细地址', "value" => $siteLocationModel->address],
                ["name" => '所在区域', "value" => $siteLocationModel->cityArea],
                ["name" => '处理结果', "value" => "驳回选址信息"],
                ["name" => '处理时间', "value" => formatDate(time())],
                ["name" => '驳回意见', "value" => $rejectReason],
            )->msgSend(["path" => "pages/site-info/index?orderNo={$siteLocationModel->orderNo}"]);

        } catch (Exception $exception) {
            handleException($exception, BaseErrorCode::$MISSION_REFUSE_SHOP_LOCATION_FAIL);
        }
    }

    /**
     * 获取选址信息
     *
     * @param int $shopId
     * @return array
     * @throws Exception
     */
    public static function shopLocationDetail(int $shopId): array
    {
        try {

            $orderObj = OpenShopMainProcessModel::query()
                                                ->where("shopId", $shopId)
                                                ->first();

            if (!$orderObj) {
                throw new ResponseHttpException(BaseErrorCode::$ORDER_NOT_EXISTS);
            }

            $shopLocation = ($shopLocation = OpenShopLocationModel::query()
                                                                  ->where("orderNo", $orderObj->orderNo)
                                                                  ->select([
                                                                      "shopAddressPrefix",
                                                                      "shopDetailAddress",
                                                                      "shopRent",
                                                                      "shopArea",
                                                                      "shopScopeProducts",
                                                                      "shopType",
                                                                      'rentPer',
                                                                      'monthlyRent',
                                                                      'shopRent',
                                                                      'depositMonth',
                                                                      'deposit',
                                                                      'payMonth'
                                                                  ])
                                                                  ->first()) ? $shopLocation->toArray() : [];

            if ($shopLocation) {
                $shopLocation["deposit"] = $shopLocation["deposit"] * 100;
            }

            return [
                "shopCode"           => OpenShopSignOrderModel::query()
                                                              ->where("orderNo", $orderObj->orderNo)
                                                              ->first()->shopCode,
                "shopLocationDetail" => $shopLocation
            ];


        } catch (Exception $exception) {
            handleException($exception, BaseErrorCode::$MISSION_SHOP_LOCATION_DETAIL_GET_FAIL);
        }
    }

}
